<template>
  <PageWrapper :class="prefixCls" title="容器列表">
    <!--- 列表中的具体内容,添加容器相关操作 --->
    <div :class="`${prefixCls}__top`">
      <a-space :bodyStyle="{ padding: '20px' }">
        <a-input v-model:value="containerNameValue" style="border-radius: 5px;" placeholder="容器名称"/>
        <a-input v-model:value="containerIdValue" style="border-radius: 5px;" placeholder="容器ID"/>
        <a-input v-model:value="imageIdValue" style="border-radius: 5px;" placeholder="镜像ID"/>
        <a-button type="primary" shape="round" @click="handleSearch">搜索</a-button>
        <a-button type="primary" shape="round" @click="handleAdd">新增容器</a-button>
        <StatisticCountdown format="s秒" title="刷新倒计时" style="margin-right: 50px" :value="countdownTime" @finish="pullNodeData" ></StatisticCountdown>
      </a-space>
    </div>
    <!--- 容器头像 容器名称 容器描述 容器owner 容器 --->
    <div :class="`${prefixCls}__content`">
      <a-list :pagination="pagination">
        <template v-for="item in listData" :key="item.id">
          <a-list-item class="list">
            <a-list-item-meta>
              <!--- 容器代表图像 --->
              <template #avatar>
                <!-- TODO:暂时写死 --->
                <Icon class="icon" icon="logos:vue" color="#1890ff" />
              </template>

              <!--- 容器名称 --->
              <template #title>
                <span>{{ item.name }}</span>
                <br>
                <div class="extra" v-if="item">
                  <!--- 添加按钮 --->
                  <a disabled="item.status == 1" @click="pushToContainerWebSSH(item)"><a-icon type="code"/> 终端</a>
                  <br>
                  <br>
                  <!--- 容器操作下拉框 --->
                  <a-dropdown :trigger="['click']" @click="getOptions(item)">
                    <a class="ant-dropdown-link" @click.prevent>
                      更多操作
                      <DownOutlined />
                    </a>
                    <template #overlay>
                      <a-menu>
                        <a-menu-item>
                          <a @click="openContainerInfo(item)">查看详情</a><br>
                        </a-menu-item>
                        <a-menu-item>
                          <a @click="showOperLog(item)">操作日志</a>
                        </a-menu-item>
                        <!--- 此处动态渲染下拉框 --->
                        <template v-for="option in containerOperation" :key="option.id">
                            <a-menu-item @click="containerOperHandle(item,option)">{{option.name}}</a-menu-item>
                          </template>
                      </a-menu>
                    </template>
                  </a-dropdown>
                </div>
              </template>

              <template #description>
                <!--- 容器描述 --->
                <div class="description">
                  简介:{{ item.description }}
                  <br>
                  ID:{{item.containerId}}
                </div>
                <!---  容器创建者 --->
                <div class="info">
                  <div><span>Owner</span>{{ item.owner }}</div>
                  <div><span>剩余使用时间</span>{{ parseInt(item.leaveMachineTime/60) }}小时{{item.leaveMachineTime%60}}分钟</div>
                </div>
                <!--- 容器状态,根据不同状态设定不同的进度条 --->
                <div class="progress">
                  <a-badge v-if="item.containerStatusType == 'waiting' " status="processing" color="yellow" :text="item.containerStatusName"/>
                  <a-badge v-else-if="item.containerStatusType == 'normal' " status="processing" color="green" :text="item.containerStatusName"/>
                  <a-badge v-else-if="item.containerStatusType == 'error' " status="processing" color="red" :text="item.containerStatusName"/>
                </div>
              </template>
            </a-list-item-meta>
          </a-list-item>
        </template>
      </a-list>
    </div>
  </PageWrapper>
  <!--- 注册弹窗 --->
  <BasicDrawer @register="containerRegister" title="查看详情" width="50%">
    <a-descriptions bordered title="容器信息">
      <a-descriptions-item :span="4" label="容器ID">{{vmContainerData.containerId}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="名称">{{vmContainerData.name}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="端口映射">{{vmContainerData.ports}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="登录账号">{{vmContainerData.sshUserName}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="登录密码">{{vmContainerData.sshPassword}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="容器状态">
        <a-badge v-if="vmContainerData.containerStatusType == 'waiting' " status="processing" color="yellow" :text="vmContainerData.containerStatusName"/>
        <a-badge v-else-if="vmContainerData.containerStatusType == 'normal' " status="processing" color="green" :text="vmContainerData.containerStatusName"/>
        <a-badge v-else-if="vmContainerData.containerStatusType == 'error' " status="processing" color="red" :text="vmContainerData.containerStatusName"/>
      </a-descriptions-item>
      <a-descriptions-item :span="4" label="描述">{{vmContainerData.description}}</a-descriptions-item>
    </a-descriptions>
    <a-descriptions bordered title="镜像信息">
      <a-descriptions-item :span="4" label="镜像ID">{{vmImageData.imageId}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="镜像地址">{{vmImageData.hubUrl}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="暴露端口">{{vmImageData.ports}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="启动指令">{{vmImageData.command}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="镜像描述">{{vmImageData.description}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="默认登录账号">{{vmImageData.sshUsername}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="默认登录密码">{{vmImageData.sshPassword}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="审核人">{{vmImageData.reviewer}}</a-descriptions-item>
    </a-descriptions>
    <a-descriptions bordered title="节点信息">
      <a-descriptions-item :span="4" label="节点ID">{{vmNodeData.nodeId}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="IP地址">{{vmNodeData.nodeIpAddress}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="节点GPU数量">{{vmNodeData.gpuNumber}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="节点当前状态">{{vmNodeData.initStatus}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="默认登录账号">{{vmNodeData.username}}</a-descriptions-item>
      <a-descriptions-item :span="4" label="默认登录密码">{{vmNodeData.password}}</a-descriptions-item>
    </a-descriptions>
  </BasicDrawer>

  <!---  新增容器弹窗 --->
  <BasicModal 
  v-bind="$attrs" 
  destroyOnClose 
  @register="register" 
  title="新增容器" 
  width="900px"
  :helpMessage="['请选择合适的镜像后,输入该容器的相关参数']">
    <!--- 1. 选择镜像部分 --->
    <div v-if="createContainerStep==1">
      <a-list :pagination="pagination">
        <a-row :gutter="8">
          <template v-for="item in imageListData" :key="item.id">
            <a-col :span="8">
              <a-list-item>
                <a-card :class="`${prefixCls}__card`" >
                  <div :class="`${prefixCls}__card-title`" >
                    <a>{{ item.name }}</a>

                    <a-radio-group v-model:value="choseImageId" name="imageRadioGroup" :class="`${prefixCls}__card-more`">
                      <a-radio :value="item.imageId" @click="choseImage(item.imageId)"></a-radio>
                    </a-radio-group>
                    
                  </div>
                  <div :class="`${prefixCls}__card-detail`"> {{item.description}} </div>                
                </a-card>
              </a-list-item>
            </a-col>
          </template>
        </a-row>
      </a-list>
    </div>
    <div v-else-if="createContainerStep==2">
      <VmContainerForm ref="registerForm" 
      @ok="submitCallback" 
      :formDisabled="disableSubmit" 
      :formBpm="false"
      :formData="formData"></VmContainerForm>
    </div>
    <template #footer>
      <a-button type="primary" v-if="createContainerStep==2" @click="toSelectImage">上一步</a-button>
      <a-button type="primary" v-if="createContainerStep==1" @click="toInputContainerParam">下一步</a-button>
      <a-button type="primary" :loading="iconLoading" v-else-if="createContainerStep==2" @click="submitCallback">完成</a-button>
    </template>
  </BasicModal>

  <!--- 输入申请理由的弹窗 --->
  <BasicModal destroyOnClose @register="registerConfirmReason" @ok="handleOk" title="请输入申请理由">
    <a-textarea v-model:value="scheduleReason" show-count :rows="8" :maxlength="256" />
  </BasicModal>
  <BasicModal width="900px"  destroyOnClose @register="registerTerminalModal"  title="终端">
    <iframe class="iframediv" :src="terminalUrl"></iframe>
    <template #footer>

    </template>
  </BasicModal>

</template>

<script lang="ts" setup>
  import { reactive, ref ,onMounted } from 'vue';
  import Icon from '/@/components/Icon/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { PageWrapper } from '/@/components/Page';
  import { deleteOne,stopContainer,startContainer,getUserUsage,list,getOperation,getImagePassList,saveOrUpdate,createSpecialSchedule } from './VmContainer.api';
  import { DownOutlined } from '@ant-design/icons-vue';
  import { BasicDrawer, useDrawer } from '/@/components/Drawer';
  import { BasicModal, useModal } from '/@/components/Modal';
  import VmContainerForm from './components/VmContainerForm.vue';
  import { Modal } from 'ant-design-vue';
  import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
  import { createVNode } from 'vue';
  import { useUserStore } from '/@/store/modules/user';
  import { StatisticCountdown  } from 'ant-design-vue';

  // 根据点击的下拉框,调用指定的方法
  function containerOperHandle(data, option) {
    console.log("点击了",option,"传入的参数是",data)
    // 1. 判断是哪种操作模式
    if (option.id == '1') {
      // 暂停容器
      handleStopContainer(data);
    } else if (option.id == '2') {
      // 启用容器
      handleStartContainer(data);
    } else if (option.id == '3') {
      // 删除容器
      handleDeleteContainer(data);
    }

  }

  function handleStopContainer(data) {
    console.log("停止了容器,数据为",data);
    stopContainer({containerId:data.containerId},handleSuccess);
  }

  function handleStartContainer(data) {
    console.log("启用了容器,数据为",data);
    startContainer({containerId:data.containerId},handleSuccess);
  }
  
  function handleDeleteContainer(data) {
    console.log("删除了容器,数据为",data);
    deleteOne({containerId:data.containerId},handleSuccess);
  }
  
  function handleSuccess() {
    loadData();
    createMessage.success('操作成功');
  }

  const userStore = useUserStore();
  const countdownTime = ref(Date.now() + 5 * 1000);

  function pullNodeData()  {
    // 重新计算倒计时
    console.log('重新计算倒计时')
    countdownTime.value = Date.now() + 30 * 1000;
    loadData();
  }

  const [registerConfirmReason,registerConfirmReasonMethods ] = useModal();

  const containerNameValue = ref<string>('');
  const containerIdValue = ref<string>('');
  const imageIdValue = ref<string>('');
  function handleSearch() {
    console.log('用户点击了搜索按钮')
    queryParam['name'] = containerNameValue.value;
    queryParam['containerId'] = containerIdValue.value;
    queryParam['imageId'] = imageIdValue.value;
    loadData();
  }

  const { createMessage } = useMessage();
  const disableSubmit = ref<boolean>(false);
  const iconLoading = ref<boolean>(false);
  const formData = ref<Record<string, any>>({
    name: '',
    description: '',
    reason: '',
    imageId: '',
    machineTime: 0,
    gpuCardNumber: 0,
    hourTime: 0,
    minuteTime: 0,
  });

  const registerForm = ref();
  const scheduleReason = ref<string>('');

  function handleOk() {
    console.log("申请理由是:",scheduleReason.value)
    formData.value.reason = scheduleReason.value
    console.log("提交到后台的数据为:",formData.value)
    // 返回数据
    createSpecialSchedule(formData.value).then((data) => {
      console.log("data", data);
      createMessage.success(data.message)
      registerConfirmReasonMethods.closeModal();
      closeModal();
    }).catch((err) => {
      console.log("err", err);
    })
  }



  function submitCallback() {
    iconLoading.value = true;
    // 1. 获取数据
    formData.value.imageId = choseImageId.value;
    formData.value.machineTime = formData.value.hourTime*60 + formData.value.minuteTime;
    console.log("点击了提交", formData);
    // 2. 做一些时间处理
    // 2. 提交到后端API中
    saveOrUpdate(formData.value, false).then((data) => {
      console.log("返回了数据!",data)
      iconLoading.value = false;
      // 走创建审核的流程
      if (data.code == 10001 || data.code == 10002) {
        // 打开一个弹窗
        Modal.confirm({
        title: '特殊配额使用申请',
        icon: createVNode(ExclamationCircleOutlined),
        content: data.message,
        onOk() {
          // 打开弹窗即可
          registerConfirmReasonMethods.openModal();
        },
      // eslint-disable-next-line @typescript-eslint/no-empty-function
      onCancel() {},
      });
      } else if (data.code == 200){
        createMessage.success(data.message);
        loadData();
        closeModal();
      }else {
        createMessage.warn(data.message)
        loadData();
        closeModal();
      }
    }).catch((err) => {
      console.log("产生了异常!",err)
    })
  }
  
  // 新增容器,直接跳转到镜像列表,然后执行容器的创建
  const createContainerStep = ref<Number>(0); // 创建步骤
  const [register, { openModal,closeModal }] = useModal(); // 注册弹窗相关

  const choseImageId = ref<string>('');

  function choseImage(id:string) {
    choseImageId.value = id;
    console.log("选中的镜像id为",choseImageId.value);
  }

  // 创建容器时的镜像卡片
  const queryImageParam = reactive<any>({});
  // 2. 列表数据定义
  // 2.1 列表数据实例
  const imageListData = ref<any>({});
  function handleAdd() {
    // 1. 修改当前步骤
    createContainerStep.value = 1;
    // 2. 获取分页参数后执行镜像数据查询 
    getImagePassList(queryImageParam).then((data)=>{
      console.log("从后端获取到的数据为",data);
      imageListData.value = data.records;
    }).catch((err)=>{
      console.log("产生异常",err);
    })
    // 3. 打开弹窗
    openModal();
  }

  // 选择完镜像后,填写镜像相关信息
  function toInputContainerParam() {
    createContainerStep.value = 2;
  }

  // 返回选择镜像
  function toSelectImage() {
    createContainerStep.value = 1;
  }

  // 注册弹窗
  const vmContainerData = ref<any>();
  const vmImageData = ref<any>();
  const vmNodeData = ref<any>();
  const [containerRegister, containerDrawerMethods] = useDrawer();
  // 点击查看详情后,打开弹窗
  function openContainerInfo(data) {
    vmContainerData.value = data;
    vmImageData.value = data.vmImage;
    vmNodeData.value = data.vmNode;
    containerDrawerMethods.openDrawer(true,data);
  }

  // 展示容器操作日志信息
  function showOperLog(data) {
    console.log(data);
  }
  
  // 动态渲染下拉框方法
  const containerOperation = ref<any>({});

  function getOptions(data) {
    console.log("点击了更多操作,加载此容器对应的操作方法",data)
    getOperation(data.id).then((reponse)=>{
      console.log("返回的数据为",reponse)
      containerOperation.value = reponse
    }).catch((err)=>{
      console.log("产生的异常为",err)
    })
  }

  // 列表基础元素设置
  const prefixCls = 'list-basic';
  const pagination = {
    show: true,
    pageSize:3,
  };

  // 列表数据设置
  // 1. 查询参数
  const queryParam = reactive<any>({});
  // 2. 列表数据定义
  // 2.1 列表数据实例
  const listData = ref<any>({});
  // 3. 定义初始化时,加载数据
  onMounted(()=>{
    loadData();
  })

  function getMonthLeaveSettings() {
    // 1. callApi
    getUserUsage().then((data) => {
      console.log('读取用户本月可用额度',data);
      userStore.setLeaveGpuCardNumber(data.remainGpuCardNumber);
      userStore.setLeaveMachineTimeHour(parseInt(data.remainIngTime/60));
      userStore.setLeaveMachineTimeMinute(data.remainIngTime%60);
    }).catch((err) => {
      console.log("获取用户数据产生异常!",err)
    })
  }
  // 3. 定义加载数据行为
  function loadData() {
    // 3.1 加载列表数据
    list(queryParam).then((data)=>{
      console.log("从后端获取到的数据为",data);
      listData.value = data.records;
    }).catch((err)=>{
      console.log("加载数据产生异常",err);
    })
    // 3.2 加载用户配额数据
    getMonthLeaveSettings();
  }

  // 4. 添加登录容器逻辑
  const webSSHServiceUrl = "http://120.24.170.16:8888/?"
  const terminalUrl = ref<string>('');
  const [registerTerminalModal,registerTerminalMethods ] = useModal();
  function pushToContainerWebSSH(record) {
    if (record.status != 1) {
      return;
    }
    // 梳理一下相关的数据
    console.log("点击展示镜像信息",record.vmImage);
    const sshUserName:string = record.sshUserName;
    const sshPassword:string = record.passwordBase64;
    const sshPort:string = record.sshPort;
    const hostName:string = record.vmNode.nodeIpAddress
    // 拼装url
    const newUrl = webSSHServiceUrl + "hostname=" + hostName    + "&" + 
                                      "username=" + sshUserName + "&" +
                                      "password=" + sshPassword + "&" +
                                      "port="     + sshPort     ;
    console.log("登录界面URL为:",newUrl);
    terminalUrl.value = newUrl;
    registerTerminalMethods.openModal();
  }


</script>

<style lang="less" scoped>

  .iframediv {
    width: 100%;
    height: 600px;
    margin: 10px auto;
    overflow: hidden;
  }
  .button {
    margin-left: 20px;
    margin-right: 20px;
  }
  .list-basic {
    &__top {
      padding: 24px;
      text-align: start;
      background-color: @component-background;
      &-col {
        margin-left: 20px;
        margin-right: 20px;
        &:not(:last-child) {
          border-right: 1px dashed @border-color-base;
        }

        div {
          margin-bottom: 12px;
          font-size: 14px;
          line-height: 22px;
          color: @text-color;
        }

        p {
          margin: 0;
          font-size: 24px;
          line-height: 32px;
          color: @text-color;
        }
      }
    }


    &__card {
      width: 300px;
      margin-bottom: -8px;

      .ant-card-body {
        padding: 16px;
      }

      &-title {
        margin-bottom: 5px;
        font-size: 16px;
        font-weight: 500;
        color: @text-color;

        .icon {
          margin-top: -5px;
          margin-right: 10px;
          font-size: 38px !important;
        }
      }

      &-more {
        float: right;
      }

      &-detail {
        padding-top: 10px;
        padding-left: 30px;
        font-size: 14px;
        color: @text-color-secondary;
      }
    }

    &__content {
      padding: 24px;
      margin-top: 12px;
      background-color: @component-background;

      .list {
        position: relative;
      }

      .icon {
        font-size: 40px !important;
      }

      .extra {
        position: absolute;
        top: 20px;
        right: 15px;
        font-weight: normal;
        color: @primary-color;
        cursor: pointer;
      }

      .description {
        display: inline-block;
        width: 40%;
      }

      .info {
        display: inline-block;
        width: 30%;
        text-align: center;
        vertical-align: top;

        div {
          display: inline-block;
          padding: 0 20px;

          span {
            display: block;
          }
        }
      }

      .progress {
        display: inline-block;
        width: 15%;
        vertical-align: top;
      }
    }
  }
</style>
